package cn.dm.example.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class CyclicBarrierExample1 {

    private static CyclicBarrier barrier = new CyclicBarrier(5);

    public static void main(String[] args) throws Exception {

        ExecutorService executor = Executors.newCachedThreadPool();

        for (int i = 0; i < 10; i++) {
            final int threadNum = i;
            Thread.sleep(1000);
            executor.execute(() -> {
                try {
                    race(threadNum);
                } catch (Exception e) {
                    log.error("exception", e);
                }
            });
        }
        executor.shutdown();
        /**
         * 结果
         * 16:36:03.072 [pool-1-thread-1] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 0 is ready
         * 16:36:04.083 [pool-1-thread-2] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 1 is ready
         * 16:36:05.096 [pool-1-thread-3] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 2 is ready
         * 16:36:06.100 [pool-1-thread-4] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 3 is ready
         * 16:36:07.104 [pool-1-thread-5] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 4 is ready
         * 16:36:07.105 [pool-1-thread-5] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 4 continue
         * 16:36:07.105 [pool-1-thread-1] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 0 continue
         * 16:36:07.105 [pool-1-thread-2] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 1 continue
         * 16:36:07.105 [pool-1-thread-3] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 2 continue
         * 16:36:07.105 [pool-1-thread-4] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 3 continue
         * 16:36:08.114 [pool-1-thread-6] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 5 is ready
         * 16:36:09.114 [pool-1-thread-3] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 6 is ready
         * 16:36:10.123 [pool-1-thread-4] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 7 is ready
         * 16:36:11.138 [pool-1-thread-1] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 8 is ready
         * 16:36:12.139 [pool-1-thread-5] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 9 is ready
         * 16:36:12.139 [pool-1-thread-5] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 9 continue
         * 16:36:12.139 [pool-1-thread-6] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 5 continue
         * 16:36:12.139 [pool-1-thread-3] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 6 continue
         * 16:36:12.140 [pool-1-thread-4] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 7 continue
         * 16:36:12.140 [pool-1-thread-1] INFO cn.dm.example.aqs.CyclicBarrierExample1 - 8 continue
         *
         * 由结果可知,因为 new CyclicBarrier(5),故10个线程分两组
         * 0到4一组共五个,都达到ready状态后才继续执行
         * 5到9一组共五个,都达到ready状态后才继续执行
         */
    }

    private static void race(int threadNum) throws Exception {
        Thread.sleep(1000);
        log.info("{} is ready", threadNum);
        barrier.await(); // 上面初始化时barrier=5,因此会等到5个时才继续进行
        log.info("{} continue", threadNum);
    }
}
